package controllers

import (
	"strconv"

	"simple-crm/models"
	"simple-crm/services"
	"simple-crm/utils"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type RoleController struct {
	db                *gorm.DB
	permissionService *services.PermissionService
}

func NewRoleController(db *gorm.DB, permissionService *services.PermissionService) *RoleController {
	return &RoleController{
		db:                db,
		permissionService: permissionService,
	}
}

// GetRoles 角色管理
func (ctrl *RoleController) GetRoles(c *gin.Context) {
	// 获取查询参数
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
	search := c.Query("search")
	status := c.Query("status")

	// 构建查询
	query := ctrl.db.Model(&models.Role{})

	// 搜索条件
	if search != "" {
		query = query.Where("name LIKE ? OR display_name LIKE ?", "%"+search+"%", "%"+search+"%")
	}

	// 状态筛选
	if status != "" {
		query = query.Where("status = ?", status)
	}

	// 统计总数
	var total int64
	query.Count(&total)

	// 分页查询
	var roles []models.Role
	offset := (page - 1) * limit
	query.Offset(offset).Limit(limit).Find(&roles)

	// 批量获取角色统计信息以优化性能
	if len(roles) > 0 {
		// 提取角色ID列表
		roleIDs := make([]uint, len(roles))
		for i, role := range roles {
			roleIDs[i] = role.ID
		}

		// 批量查询权限数量
		var permissionCounts []struct {
			RoleID uint
			Count  int64
		}
		ctrl.db.Table("role_permissions").Select("role_id, COUNT(*) as count").
			Where("role_id IN ?", roleIDs).Group("role_id").Scan(&permissionCounts)

		// 批量查询用户数量
		var userCounts []struct {
			RoleID uint
			Count  int64
		}
		ctrl.db.Table("user_roles").Select("role_id, COUNT(*) as count").
			Where("role_id IN ?", roleIDs).Group("role_id").Scan(&userCounts)

		// 创建映射表以快速查找
		permissionCountMap := make(map[uint]int64)
		for _, pc := range permissionCounts {
			permissionCountMap[pc.RoleID] = pc.Count
		}

		userCountMap := make(map[uint]int64)
		for _, uc := range userCounts {
			userCountMap[uc.RoleID] = uc.Count
		}

		// 为每个角色设置统计信息
		for i := range roles {
			roles[i].PermissionCount = int(permissionCountMap[roles[i].ID])
			roles[i].UserCount = int(userCountMap[roles[i].ID])
		}
	}

	responseData := gin.H{
		"list":  roles,
		"total": total,
		"page":  page,
		"limit": limit,
	}

	utils.SuccessWithData(c, responseData)
}

func (ctrl *RoleController) CreateRole(c *gin.Context) {
	var req struct {
		Name          string `json:"name" binding:"required"`
		DisplayName   string `json:"display_name" binding:"required"`
		Description   string `json:"description"`
		PermissionIDs []uint `json:"permission_ids"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.ErrorWithMessage(c, "参数错误: "+err.Error())
		return
	}

	role := models.Role{
		Name:        req.Name,
		DisplayName: req.DisplayName,
		Description: req.Description,
		Status:      "active",
	}

	if err := ctrl.db.Create(&role).Error; err != nil {
		utils.ErrorWithMessage(c, "创建角色失败")
		return
	}

	// 分配权限
	if len(req.PermissionIDs) > 0 {
		var permissions []models.Permission
		ctrl.db.Where("id IN ?", req.PermissionIDs).Find(&permissions)
		ctrl.db.Model(&role).Association("Permissions").Append(permissions)
	}

	utils.SuccessWithMessage(c, "角色创建成功", nil)
}

// GetRole 获取角色详情
func (ctrl *RoleController) GetRole(c *gin.Context) {
	id, _ := strconv.ParseUint(c.Param("id"), 10, 32)

	var role models.Role
	if err := ctrl.db.Preload("Permissions").First(&role, id).Error; err != nil {
		utils.ErrorWithMessage(c, "角色不存在")
		return
	}

	utils.SuccessWithData(c, role)
}

// UpdateRole 更新角色
func (ctrl *RoleController) UpdateRole(c *gin.Context) {
	id, _ := strconv.ParseUint(c.Param("id"), 10, 32)

	var req struct {
		Name        string `json:"name" binding:"required"`
		DisplayName string `json:"display_name" binding:"required"`
		Description string `json:"description"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.ErrorWithMessage(c, "参数错误")
		return
	}

	var role models.Role
	if err := ctrl.db.First(&role, id).Error; err != nil {
		utils.ErrorWithMessage(c, "角色不存在")
		return
	}

	role.Name = req.Name
	role.DisplayName = req.DisplayName
	role.Description = req.Description

	if err := ctrl.db.Save(&role).Error; err != nil {
		utils.ErrorWithMessage(c, "更新角色失败")
		return
	}

	utils.SuccessWithMessage(c, "角色更新成功", nil)
}

// DeleteRole 删除角色
func (ctrl *RoleController) DeleteRole(c *gin.Context) {
	id, _ := strconv.ParseUint(c.Param("id"), 10, 32)

	// 检查角色是否被使用
	var count int64
	ctrl.db.Model(&models.UserRole{}).Where("role_id = ?", id).Count(&count)
	if count > 0 {
		utils.ErrorWithMessage(c, "角色正在使用中，无法删除")
		return
	}

	if err := ctrl.db.Delete(&models.Role{}, id).Error; err != nil {
		utils.ErrorWithMessage(c, "删除角色失败")
		return
	}

	utils.SuccessWithMessage(c, "角色删除成功", nil)
}

// RolesIndex 角色管理页面
func (ctrl *RoleController) RolesIndex(c *gin.Context) {
	c.HTML(200, "roles/index.html", gin.H{
		"title": "角色管理",
		"user":  c.MustGet("user"),
		"CurrentPage": "roles",
	})
}

// RoleCreatePage 角色创建页面
func (ctrl *RoleController) RoleCreatePage(c *gin.Context) {
	c.HTML(200, "roles/create.html", gin.H{
		"title": "创建角色",
		"user":  c.MustGet("user"),
		"CurrentPage": "role-create",
	})
}

// RoleEditPage 角色编辑页面
func (ctrl *RoleController) RoleEditPage(c *gin.Context) {
	c.HTML(200, "roles/edit.html", gin.H{
		"title": "编辑角色",
		"user":  c.MustGet("user"),
		"CurrentPage": "role-edit",
	})
}

// RoleDetailPage 角色详情页面
func (ctrl *RoleController) RoleDetailPage(c *gin.Context) {
	c.HTML(200, "roles/detail.html", gin.H{
		"title": "角色详情",
		"user":  c.MustGet("user"),
		"CurrentPage": "role-detail",
	})
}

// ToggleRoleStatus 切换角色状态
func (ctrl *RoleController) ToggleRoleStatus(c *gin.Context) {
	id, _ := strconv.ParseUint(c.Param("id"), 10, 32)

	var role models.Role
	if err := ctrl.db.First(&role, id).Error; err != nil {
		utils.ErrorWithMessage(c, "角色不存在")
		return
	}

	// 切换状态
	if role.Status == "active" {
		role.Status = "inactive"
	} else {
		role.Status = "active"
	}

	if err := ctrl.db.Save(&role).Error; err != nil {
		utils.ErrorWithMessage(c, "状态更新失败")
		return
	}

	utils.SuccessWithMessage(c, "状态更新成功", nil)
}

// GetRolePermissions 获取角色权限
func (ctrl *RoleController) GetRolePermissions(c *gin.Context) {
	id, _ := strconv.ParseUint(c.Param("id"), 10, 32)

	var role models.Role
	if err := ctrl.db.Preload("Permissions").First(&role, id).Error; err != nil {
		utils.ErrorWithMessage(c, "角色不存在")
		return
	}

	utils.SuccessWithData(c, role.Permissions)
}

// UpdateRolePermissions 更新角色权限
func (ctrl *RoleController) UpdateRolePermissions(c *gin.Context) {
	id, _ := strconv.ParseUint(c.Param("id"), 10, 32)

	var req struct {
		PermissionIDs []uint `json:"permission_ids"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.ErrorWithMessage(c, "参数错误")
		return
	}

	var role models.Role
	if err := ctrl.db.First(&role, id).Error; err != nil {
		utils.ErrorWithMessage(c, "角色不存在")
		return
	}

	// 清除现有权限
	ctrl.db.Model(&role).Association("Permissions").Clear()

	// 分配新权限
	if len(req.PermissionIDs) > 0 {
		var permissions []models.Permission
		ctrl.db.Where("id IN ?", req.PermissionIDs).Find(&permissions)
		ctrl.db.Model(&role).Association("Permissions").Append(permissions)
	}

	utils.SuccessWithMessage(c, "权限更新成功", nil)
}

// BatchDeleteRoles 批量删除角色
func (ctrl *RoleController) BatchDeleteRoles(c *gin.Context) {
	var req struct {
		RoleIDs []uint `json:"role_ids" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		utils.ErrorWithMessage(c, "参数错误")
		return
	}

	// 检查角色是否被使用
	var count int64
	ctrl.db.Model(&models.UserRole{}).Where("role_id IN ?", req.RoleIDs).Count(&count)
	if count > 0 {
		utils.ErrorWithMessage(c, "部分角色正在使用中，无法删除")
		return
	}

	// 批量删除
	if err := ctrl.db.Where("id IN ?", req.RoleIDs).Delete(&models.Role{}).Error; err != nil {
		utils.ErrorWithMessage(c, "批量删除失败")
		return
	}

	utils.SuccessWithMessage(c, "批量删除成功", nil)
}

// CheckRoleName 检查角色名称是否存在
func (ctrl *RoleController) CheckRoleName(c *gin.Context) {
	name := c.Query("name")
	if name == "" {
		utils.ErrorWithMessage(c, "角色名称不能为空")
		return
	}

	var count int64
	ctrl.db.Model(&models.Role{}).Where("name = ?", name).Count(&count)

	utils.SuccessWithData(c, map[string]bool{
		"exists": count > 0,
	})
}

// GetRoleUsers 获取角色关联的用户
func (ctrl *RoleController) GetRoleUsers(c *gin.Context) {
	id, _ := strconv.ParseUint(c.Param("id"), 10, 32)

	var users []models.User
	if err := ctrl.db.Joins("JOIN user_roles ON users.id = user_roles.user_id").
		Where("user_roles.role_id = ?", id).
		Select("users.id, users.username, users.real_name, users.email, users.status, users.created_at").
		Find(&users).Error; err != nil {
		utils.ErrorWithMessage(c, "获取角色用户失败")
		return
	}

	utils.SuccessWithData(c, users)
}

// GetRoleStats 获取角色统计信息
func (ctrl *RoleController) GetRoleStats(c *gin.Context) {
	var totalRoles int64
	var activeRoles int64
	var inactiveRoles int64
	var totalPermissions int64

	// 统计总角色数
	ctrl.db.Model(&models.Role{}).Count(&totalRoles)
	// 统计启用角色数
	ctrl.db.Model(&models.Role{}).Where("status = ?", "active").Count(&activeRoles)
	// 统计停用角色数
	ctrl.db.Model(&models.Role{}).Where("status = ?", "inactive").Count(&inactiveRoles)
	// 统计权限总数
	ctrl.db.Model(&models.Permission{}).Count(&totalPermissions)

	stats := gin.H{
		"total_roles":       totalRoles,
		"active_roles":      activeRoles,
		"inactive_roles":    inactiveRoles,
		"total_permissions": totalPermissions,
	}

	utils.SuccessWithData(c, stats)
}
